<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>首页</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
  <div id="app">
    <h2>Hello Vue-Router!</h2>
    <p>
      <!-- 使用 router-link 组件来导航 -->
      <!-- 通过传入 `to` 属性来指定链接跳转 -->
      <!-- <router-link> 标签默认会被渲染成一个 <a> 标签 -->
      <router-link to="/foo">Go to Foo</router-link>
      <br>
      <router-link to="/bar">Go to Bar</router-link>
      <br>
      <router-link to="/user/isok">Go to User-isok</router-link>
      <br>
      <router-link to="/user/love">Go to User-love</router-link>
      <br>
      <router-link to="/profile-love">Go to profile-love</router-link>
      <br>
      <router-link to="/profile-isok">Go to profile-isok</router-link>
    </p>

    <!-- 路由出口 -->
    <!-- 路由匹配到的组件将在这里渲染 -->
    <router-view></router-view>

    <!-- <pre>{{ JSON.stringify($route, null, 2) }}</pre> -->
    <!-- <pre>{{ $route }}</pre> -->
  </div>

  <script>
    // 1. 定义路由组件
    const Foo = { template: '<div>foo</div>' };
    const Bar = { template: '<div>bar</div>' };
    const Profile = {
      template: '<div>profile {{ $route.params.pathMatch }}</div>',
      beforeRouteUpdate(to, from, next) {
        console.group("导航守卫 =>");
        console.log("to   =>", to);
        console.log("from =>", from);
        console.groupEnd();
        next();
      }
    };
    // $route 路由对象
    // $route.params 路由传递参数对象 「user/:id」 其中id为key，真实传递结果为value
    const User = {
      template: '<div>User {{ $route.params }}</div>',
      watch: {
        // 如官方文档所述，当我们使用路由参数时, 例如从`/user/foo`导航到`/user/bar`, 原来的组件实例是会被复用的！！！
        // 因为两个路由都渲染同个组件, 比起销毁再创建, 复用则显得更加高效, 不过, 这也就意味着组件的生命周期钩子将不会再被调用
        // 所以我们可以取巧: 监听$route对象的改变, 这样我们就可以对路由参数的变化作出一些响应响应
        $route(to, from) {
          console.group("路由已复用 生命周期不调用 =>");
          console.log("to =>", to);
          console.log("from =>", from);
          console.groupEnd();
        }
      },
      // 同上监听$route对象
      // 使用`beforeRouteUpdate`导航守卫也能达到效果
      beforeRouteUpdate(to, from, next) {
        console.group("导航守卫 =>");
        console.log("to =>", to);
        console.log("from =>", from);
        console.groupEnd();
        // ...
        // ！！！使用导航守卫的话记得调用 next() 不然可就卡这 出不去了哦~
        next();
      }
    };
    const NotFound = { template: '<div>404</div>' };

    // 2. 定义路由 「创建路由对象」
    // 说明: 每个路由应该映射一个组件, 其中`component`可以是
    // 1. 通过 Vue.extend() 所创建的组件构造器
    // 2. 或者只是一个组件配置对象
    const routes = [
      {
        path: '/foo',
        component: Foo,
      },
      {
        path: '/bar',
        component: Bar
      },
      {
        // 动态路径参数 以冒号开头
        path: '/user/:id',
        component: User
      },
      {
        path: '/profile-*',
        component: Profile,
        meta: {
          requireAuth: true
        }
      },
      {
        // `*` 通配符 匹配全部路由 「一般放在最后」
        path: '*',
        component: NotFound
      }
    ]

    // 3. 创建`router`实例, 然后传入`路由对象`进行配置
    const router = new VueRouter({
      routes
    })

    // 4. 创建`Vue`实例, 将`router`挂载至Vue实例上
    const app = new Vue({
      router
    }).$mount('#app');
  </script>
</body>

</html>